home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 001 / speech / speech.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  9KB  |  332 lines

  1. /* Here is a sample speech demo program that compiles on
  2.  * Amiga (Lattice) C.  It can be thought of as a stripped
  3.  * down version of the speechtoy (lucas).  I haven't 
  4.  * provided the graphics for the drawing of the mouth,
  5.  * but the access to the mouth variables is shown here.
  6.  * 
  7.  * It is the sample program from the rev 1.1 ROM KERNEL
  8.  * manual, now at the printers.
  9.  * 
  10.  * Rob Peck.   
  11.  *
  12.  * This code may be freely utilized to create programs for the Amiga.
  13.  */
  14.  
  15.  
  16.  
  17. #include "exec/types.h"
  18. #include "exec/exec.h"
  19.  
  20. #include "exec/nodes.h"
  21. #include "exec/lists.h"
  22. #include "exec/memory.h"
  23. #include "exec/interrupts.h"
  24. #include "exec/ports.h"
  25. #include "exec/libraries.h"
  26. #include "exec/io.h"
  27. #include "exec/tasks.h"
  28. #include "exec/execbase.h"
  29.  
  30. #include "devices/narrator.h"
  31. #include "libraries/translator.h"
  32.  
  33. struct MsgPort *readport=0;
  34. struct MsgPort *writeport=0;
  35.  
  36. extern struct MsgPort *CreatePort();
  37. extern struct IORequest *CreateExtIO();    
  38.  
  39. struct narrator_rb *writeNarrator=0;
  40. struct mouth_rb *readNarrator=0;
  41. struct Library *TranslatorBase=0;
  42. UBYTE *sampleinput;        /* pointer to sample input string */
  43. UBYTE outputstring[500];    /* place to put the translation */
  44. SHORT rtnCode;            /* return code from function */
  45. SHORT readError;
  46. SHORT writeError;
  47. SHORT error;
  48. BYTE  audChanMasks[4] = { 3,5,10,12 }; /* which channels to use */
  49.  
  50. #define CANT_OPEN_TRANSLATOR -100
  51. #define CANT_OPEN_NARRATOR -200
  52. #define CREATE_PORT_PROBLEMS -300
  53. #define CREATE_IO_PROBLEMS -400
  54. #define CANT_PERFORM_WRITE -500
  55. #define REVISION 1
  56.  
  57. extern struct Library *OpenLibrary();
  58.  
  59. main()
  60. {
  61.     TranslatorBase = OpenLibrary("translator.library",REVISION);
  62.     if(TranslatorBase == NULL) exit (CANT_OPEN_TRANSLATOR);
  63.     sampleinput = "this is a test"; /* a test string of 14 characters */
  64.     rtnCode = Translate(sampleinput,14,outputstring,500);
  65.     error = rtnCode + 100;
  66.     if(rtnCode != 0) goto cleanup0;
  67.     
  68.     writeport = CreatePort(0,0);
  69.     if(writeport == NULL) { error=CREATE_PORT_PROBLEMS; goto cleanup1; }
  70.     readport = CreatePort(0,0);
  71.     if(readport == NULL) { error=CREATE_PORT_PROBLEMS; goto cleanup2; }
  72.     writeNarrator = (struct narrator_rb *)CreateExtIO(writeport,
  73.                     sizeof(struct narrator_rb));
  74.     if(writeNarrator == NULL) { error=CREATE_IO_PROBLEMS; goto cleanup3; }
  75.     readNarrator = (struct mouth_rb *)CreateExtIO(readport,
  76.                     sizeof(struct mouth_rb));
  77.  
  78.     if(readNarrator == NULL) { error=CREATE_IO_PROBLEMS; goto cleanup4; }
  79. /* SET UP THE PARAMETERS FOR THE WRITE-MESSAGE TO THE NARRATOR DEVICE */
  80.  
  81.     /* show where to find the channel masks */
  82.     writeNarrator->ch_masks = (audChanMasks);
  83.  
  84.     /* and tell it how many of them there are */
  85.     writeNarrator->nm_masks = sizeof(audChanMasks);    
  86.  
  87.     /* tell it where to find the string to speak */    
  88.     writeNarrator->message.io_Data = (APTR)outputstring;
  89.  
  90.     /* tell it how many characters the translate function returned */
  91.     writeNarrator->message.io_Length = strlen(outputstring);
  92.  
  93.     /* if nonzero, asks that mouths be calculated during speech */
  94.     writeNarrator->mouths = 1;
  95.  
  96.     /* tell it this is a write-command */
  97.     writeNarrator->message.io_Command = CMD_WRITE;
  98.  
  99. /* Open the device  */
  100.  
  101.     error = OpenDevice("narrator.device", 0, writeNarrator, 0);
  102.     if(error != 0) goto cleanup4;
  103.  
  104. /* SET UP THE PARAMETERS FOR THE READ-MESSAGE TO THE NARRATOR DEVICE */
  105.  
  106.     /* tell narrator for whose speech a mouth is to be generated */
  107.     readNarrator->voice.message.io_Device = 
  108.         writeNarrator->message.io_Device;
  109.     readNarrator->voice.message.io_Unit = 
  110.         writeNarrator->message.io_Unit;
  111.  
  112.     readNarrator->width = 0;
  113.     readNarrator->height = 0;    /* initial mouth parameters */
  114.  
  115.     readNarrator->voice.message.io_Command = CMD_READ;
  116.         /* initial error value */
  117.     readNarrator->voice.message.io_Error = 0;    
  118.  
  119. /* Send an asynchronous write request to the device */
  120.  
  121.     writeError = SendIO(writeNarrator);
  122.     if(writeError != NULL) { error=CANT_PERFORM_WRITE; goto cleanup5; }
  123.     /* return immediately, run tasks concurrently */
  124.  
  125. /* keep sending reads until it comes back saying "no write in progress" */
  126.  
  127.     while((readError = readNarrator->voice.message.io_Error) != 
  128.         ND_NoWrite)
  129.     {
  130.         DoIO(readNarrator);
  131.         /* put task to sleep waiting for a different
  132.          * mouth shape or return of the message block
  133.          * with the error field showing no write in
  134.          * process
  135.          */
  136.         DrawMouth(readNarrator->width,readNarrator->height);
  137.         /* user's own unique routine, not provided here */
  138.     }
  139.  
  140.     Delay(30);
  141.  
  142.     rtnCode = Translate("No it is not",13,outputstring,500);
  143.     writeNarrator->sex = FEMALE;
  144.     writeNarrator->pitch = MAXPITCH;  /* raise pitch from default value */
  145.     writeNarrator->message.io_Data = (APTR)outputstring;
  146.     writeNarrator->message.io_Length = strlen(outputstring);
  147.     DoIO(writeNarrator);
  148.     
  149.     Delay(30);
  150.  
  151.     rtnCode = Translate("Please! I am speaking now!",26,outputstring,500);
  152.     writeNarrator->sex = MALE;
  153.     writeNarrator->pitch = DEFPITCH;
  154.     writeNarrator->message.io_Data = (APTR)outputstring;
  155.     writeNarrator->message.io_Length = strlen(outputstring);
  156.     DoIO(writeNarrator);
  157.  
  158.     Delay(30);
  159.  
  160.     rtnCode = Translate(
  161.         "Well, you are not very interesting, so I am going home!", 
  162.         55,outputstring,500);
  163.     writeNarrator->sex = FEMALE;
  164.     writeNarrator->pitch = MAXPITCH;
  165.     writeNarrator->message.io_Data = (APTR)outputstring;
  166.     writeNarrator->message.io_Length = strlen(outputstring);
  167.     DoIO(writeNarrator);
  168.  
  169.     Delay(30);
  170.  
  171.     rtnCode = Translate("Bye Bye",7,outputstring,500);
  172.     writeNarrator->sex = MALE;
  173.     writeNarrator->pitch = DEFPITCH;
  174.     writeNarrator->rate = 7;    /* slow him down */
  175.     writeNarrator->message.io_Data = (APTR)outputstring;
  176.     writeNarrator->message.io_Length = strlen(outputstring);
  177.     DoIO(writeNarrator);
  178.  
  179.     cleanup5:
  180.     if(writeNarrator != 0)
  181.         CloseDevice(writeNarrator);
  182.                 /* terminate access to the device */
  183.  
  184.     /* now return system memory to the memory allocator */ 
  185.  
  186.     cleanup4:
  187.     if(readNarrator != 0)
  188.         DeleteExtIO(readNarrator,sizeof(struct mouth_rb));
  189.     cleanup3:
  190.     if(writeNarrator != 0)
  191.         DeleteExtIO(writeNarrator,sizeof(struct narrator_rb));
  192.     cleanup2:
  193.     if(readport != 0)
  194.         DeletePort(readport);
  195.     cleanup1:
  196.     if(writeport != 0)
  197.         DeletePort(writeport);
  198.     cleanup0:
  199.     if(TranslatorBase != 0)
  200.            CloseLibrary(TranslatorBase);
  201.                 /* terminate access to the library */
  202.     
  203.     if(error != 0) exit(error);
  204. } /* end of test */    
  205.  
  206. DrawMouth(w,h)
  207. SHORT w,h;
  208. {    return(0);    /* dummy routine */    }
  209.  
  210. int strlen(string)
  211. char *string;
  212. {
  213.     int i,length;
  214.     length = -1;
  215.     for(i=0; i<256; i++)    /* 256 characters max length at this time */
  216.         {
  217.         if(*string++ == '\0') { length = i+1; break; };
  218.         }
  219.     return(length);
  220. }
  221.  
  222.  
  223. /***********************************************************************
  224. *
  225. *    Exec Support Function -- Extended IO Request
  226. *
  227. ***********************************************************************/
  228.  
  229. extern APTR AllocMem();
  230.  
  231. /****** exec_support/CreateExtIO **************************************
  232. *
  233. *   NAME    
  234. *    CreateExtIO() -- create an Extended IO request
  235. *
  236. *   SYNOPSIS
  237. *    ioReq = CreateExtIO(ioReplyPort,size);   
  238. *
  239. *   FUNCTION
  240. *    Allocates memory for and initializes a new IO request block
  241. *    of a user-specified number of bytes.
  242. *
  243. *   INPUTS
  244. *    ioReplyPort - a pointer to an already initialized
  245. *        message port to be used for this IO request's reply port.
  246. *
  247. *   RESULT
  248. *    Returns a pointer to the new block.  Pointer is of the type
  249. *    struct IORequest.
  250. *
  251. *    0 indicates inability to allocate enough memory for the request block
  252. *    or not enough signals available.
  253. *
  254. *   EXAMPLE
  255. *    struct IORequest *myBlock;
  256. *    if( (myBlock = CreateExtIO(myPort,sizeof(struct IOExtTD)) == NULL)
  257. *        exit(NO_MEM_OR_SIGNALS);
  258. *
  259. *    example used to allocate space for IOExtTD (trackdisk driver
  260. *    IO Request block for extended IO operations).
  261. *
  262. *   SEE ALSO
  263. *    DeleteExtIO
  264. *
  265. ***********************************************************************/
  266.  
  267. struct IORequest *CreateExtIO(ioReplyPort,size)
  268.     struct MsgPort *ioReplyPort;
  269.     LONG size;
  270. {
  271.     struct IORequest *ioReq;
  272.  
  273.     if (ioReplyPort == 0)
  274.     return ((struct IORequest   *) 0);
  275.  
  276.     ioReq = (struct IORequest *)AllocMem (size, MEMF_CLEAR | MEMF_PUBLIC);
  277.  
  278.     if (ioReq == 0)
  279.     return ((struct IORequest   *) 0);
  280.  
  281.     ioReq -> io_Message.mn_Node.ln_Type = NT_MESSAGE;
  282.     ioReq -> io_Message.mn_Node.ln_Pri = 0;
  283.  
  284.     ioReq -> io_Message.mn_ReplyPort = ioReplyPort;
  285.     ioReq -> io_Message.mn_Length = (size - sizeof(struct Message));
  286.                         /* new (rap) */
  287.     return (ioReq);
  288. }
  289.  
  290. /****** exec_support/DeleteExtIO **************************************
  291. *
  292. *   NAME
  293. *    DeleteExtIO() - return memory allocated for extended IO request
  294. *
  295. *   SYNOPSIS
  296. *    DeleteExtIO(ioReq,size);
  297. *
  298. *   FUNCTION
  299. *    See summary line at NAME.  Also frees the signal bit which
  300. *    had been allocated by the call to CreateExtIO.
  301. *
  302. *   INPUTS
  303. *    A pointer to the IORequest block whose resources are to be freed.
  304. *
  305. *   RESULT
  306. *    Frees the memory.  Returns (no error conditions shown)
  307. *
  308. *   EXAMPLE
  309. *    struct IORequest *myBlock;
  310. *    DeleteExtIO(myBlock,(sizeof(struct IOExtTD)));
  311. *        
  312. *    example shows that CreateExtIO had been used to create a trackdisk
  313. *    (extended) IO Request block.
  314. *
  315. *   SEE ALSO
  316. *    CreateExtIO
  317. *
  318. **************************************************************************/
  319.  
  320. DeleteExtIO(ioExt,size)
  321.     struct IORequest *ioExt;
  322.     LONG size;
  323. {
  324.     ioExt -> io_Message.mn_Node.ln_Type = 0xff;
  325.     ioExt -> io_Device = (struct Device *) -1;
  326.     ioExt -> io_Unit = (struct Unit *) -1;
  327.  
  328.     FreeMem (ioExt, size);
  329. }
  330.  
  331.  
  332.